
//
//  WBNetworkManager.swift
//  SinaWebo
//
//  Created by 亚杏 on 2017/5/16.
//  Copyright © 2017年 oms. All rights reserved.
//

import UIKit
import AFNetworking

//Swift枚举支持任意类型
enum WBHTTPMethod {
    case GET
    case POST
}
class WBNetworkManager: AFHTTPSessionManager {
    //单例,静态区/常量/闭包
    /// 如果需要设置请求的属性,可在闭包中添加
    /// 在第一次访问时，执行闭包，并且将结果保存在 shared 常量中
    static let shared: WBNetworkManager = {
        // 实例化对象
        let manager = WBNetworkManager()

        // 设置响应反序列化支持的数据类型
        manager.responseSerializer.acceptableContentTypes?.insert("text/plain")

        // 返回对象
        return manager
    }()

    //用户帐户的属性
    lazy var userAccount = WBUserAccount()

    var userLogin : Bool{
        return userAccount.access_token != nil
    }

    //MARK: 上传文件：必须是POST方法，Get只能获取
    /// 封闭AFN的上传文件方法
    /// - Parameters:
    ///   - URLString: URLString description
    ///   - parameters: 参数字典
    ///   - name: 接收上传数据的服务器字段
    ///   - data: 要上传的二进制数据
    ///   - completed: 完成回调
    func upload(URLString: String, parameters: [String : AnyObject]?, name: String, data: Data, completed: @escaping ((AnyObject?, Bool) -> ())) {

        post(URLString, parameters: parameters, constructingBodyWith: { (formData) in
            //创建 formData
            //1. data: 需要上传的二进制数据
            //2. name: 服务器接收数据的字段名
            //3. fileName: 保存在服务器的文件名，大多数服务器上传图片完成后，会生成缩略图，中图，大图等
            //4. mimeType: 告诉服务器上传文件的类型，如果不想告诉，可以使用 application/octet-stream image/png image/jpg image/gif
            formData.appendPart(withFileData: data, name: name, fileName: "xxx", mimeType: "application/octet-stream")

        }, progress: nil, success: { (_, json) in
            completed(json as AnyObject, true)

        }) { (task, error) in
            if(task?.response as? HTTPURLResponse)?.statusCode == 403{
                print("token失效")

                //发送通知（本方法不知道被谁调用，谁接收通知谁处理，提示用户再次登录）
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: WBUserShouldLoginNotification), object: "bad token")
            }

            completed(nil,false)

        }


    }

    /// MARK: 专门拼接token 的网络请求方法
    /// - Parameters:
    ///   - Method: <#Method description#>
    ///   - URLString: <#URLString description#>
    ///   - parameters: <#parameters description#>
    ///   - name: 上传文件使用的字段名
    ///   - data: 上传的二进制文件数据
    ///   - completed: 完成回调
    func tokenRequest(Method:WBHTTPMethod = .GET, URLString: String,parameters: [String: AnyObject]?, name: String? = nil, data: Data? = nil, completed:@escaping ((_ json: AnyObject?, _ isSuccess: Bool)->())) {

        //判断token是否为nil,为nil直接返回
        guard let token = userAccount.access_token else {
            //发送通知，提示用户登录
            print("无token，需要登录")
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: WBUserShouldLoginNotification), object: nil)
            
            completed(nil, false)
            return
        }

        //判断参数字典是否存在，如果为nil，应新建一个字典 
        var parameters = parameters
        if parameters == nil {
            parameters = [String : AnyObject]()
        }

        parameters!["access_token"] = token as AnyObject

        //3. 判断 name 和 data
        if let name = name,let data = data {
            //上传文件
            upload(URLString: URLString, parameters: parameters, name: name, data: data, completed: completed)
        } else {
            //上传一般数据
            request(Method: Method, URLString: URLString, parameters: parameters, completed: completed)
        }
    }

    ///MARK: 封装网络请求方法
    ///
    /// - Parameters:
    ///   - Method: GET/POST, 默认是GET请求
    ///   - URLString: 请求地址
    ///   - parameters: 参数
    ///   - completed: 结束回调
    func request(Method:WBHTTPMethod = .GET, URLString: String,parameters: [String: AnyObject]?, completed:@escaping ((_ json: AnyObject?, _ isSuccess: Bool)->())) {

        /// 定义成功回调闭包
        let success = { (task: URLSessionDataTask,json: Any?)->() in
            completed(json as AnyObject?,true)
        }

        /// 定义失败回调闭包
        let failure = {(task: URLSessionDataTask?, error: Error)->() in
            if(task?.response as? HTTPURLResponse)?.statusCode == 403{
                print("token失效")

                //发送通知（本方法不知道被谁调用，谁接收通知谁处理，提示用户再次登录）
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: WBUserShouldLoginNotification), object: "bad token")
            }
            
            completed(nil,false)
        }

        /// 通过请求方法,执行不同的请求
        // 如果是 GET 请求
        if Method == .GET { // GET

            get(URLString, parameters: parameters, progress: nil, success: success, failure: failure)

        } else { // POST

            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
    }

}
